using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;

namespace Pinwheel.LSerialize
{
    public unsafe partial struct LStreamWriter
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int AssistUnmanagedValue<T>(ref T value) where T : unmanaged
        {
            fixed (void* ptr = &value)
            {
                return AssistUnmanagedValue((byte*)ptr, sizeof(T));
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int AssistUnmanagedValue(byte* ptr, int length) => assist->PushBytes(ptr, length);
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int AssistWriteUnmanaged<T>(T value) where T : unmanaged
        {
            int size = sizeof(T);
            var ptr = &value;
            assist->PushBytes((byte*)ptr, size);
            return size;
        }
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int AssistWriteUnmanaged<T>(T* value) where T : unmanaged
        {
            int size = sizeof(T);
            assist->PushBytes((byte*)value, size);
            return size;
        }
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int AssistValHeader(ValHeader value)
        {
            int size = sizeof(ValHeader);
            var ptr = &value;
            assist->PushBytes((byte*)ptr, size);
            return size;
        }
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int WriteRefHeader(RefHeader value)
        {
            int size = sizeof(RefHeader);
            var ptr = &value;
            buffer->PushBytes((byte*)ptr, size);
            return size;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int HandleUnmanagedStruct<T>(out T* ptrHeader) where T : unmanaged =>
            buffer->HandleUnmanagedStruct(out ptrHeader);
    }
}
